package cool.mtc.security.auth;

import cool.mtc.security.data.model.UserDetailsSupport;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.Authentication;

/**
 * @author yz
 */
public abstract class AuthTemplate {

    public final Authentication authenticate(Authentication authentication) {
        AuthToken authToken = (AuthToken) authentication;

        // 前置检查
        this.handlePreCheck(authToken.getForm());

        // 获取用户信息
        UserDetailsSupport user = this.loadUserDetails(authToken.getForm());

        // 后置检查
        this.handlePostCheck(authToken.getForm(), user);

        // 检查用户状态
        this.handleCheckUserStatus(user);

        // 处理返回结果
        AbstractAuthenticationToken token = this.handleResult(authToken.getForm(), user);
        token.setDetails(user);
        return token;
    }

    /**
     * 前置检查
     * <p>
     * 获取用户信息前执行，可用来检查token是否正确
     */
    protected void handlePreCheck(AuthFormSupport formSupport) {
    }

    /**
     * 后置检查
     * <p>
     * 获取用户信息后执行，可用来检查密码是否正确
     */
    protected void handlePostCheck(AuthFormSupport formSupport, UserDetailsSupport userSupport) {
    }

    /**
     * 检查用户状态
     */
    protected void handleCheckUserStatus(UserDetailsSupport userSupport) {
        userSupport.handleCheckUserStatus();
    }

    /**
     * 获取用户信息
     *
     * @return 返回一个非空的对象
     */
    protected abstract UserDetailsSupport loadUserDetails(AuthFormSupport formSupport);

    protected abstract AuthToken handleResult(AuthFormSupport formSupport, UserDetailsSupport userSupport);

}
